package cn.schoolwow.quickdao.module.database.dml.json.flow.insert.get;

import cn.schoolwow.quickdao.module.database.dml.common.domain.ManipulationOption;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.List;

public class DistinguishExistJSONArrayFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        JSONArray existJSONArray = new JSONArray();
        flowContext.putTemporaryData("existJSONArray", existJSONArray);

        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);
        if(manipulationOption.uniqueFieldNames.size()==1){
            distinguishBySingleColumn(flowContext);
        }else if(manipulationOption.uniqueFieldNames.size()>1){
            distinguishByMultipleUniqueField(flowContext);
        }

        setNotExistJSONObjectSet(flowContext);
        JSONArray notExistJSONArray = (JSONArray) flowContext.getData("notExistJSONArray");
        if(existJSONArray.isEmpty()&&notExistJSONArray.isEmpty()){
            throw new IllegalArgumentException("逻辑执行异常!存在实例和不存在实例个数都为0!");
        }
    }

    @Override
    public String name() {
        return "区分实例是否存在";
    }

    private void distinguishBySingleColumn(FlowContext flowContext){
        JSONArray existJSONArray = (JSONArray) flowContext.getData("existJSONArray");
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);
        String singleColumnName = manipulationOption.uniqueFieldNames.iterator().next();
        JSONArray instances = (JSONArray) flowContext.checkData("instances");

        flowContext.startFlow(new GetSingleColumnValueListFlow())
                .putTemporaryData("singleColumnName", singleColumnName)
                .execute();
        List<String> singleColumnValueList = (List<String>) flowContext.getData("singleColumnValueList");
        if(singleColumnValueList.isEmpty()){
            return;
        }

        for(int i=0;i<instances.size();i++){
            JSONObject instance = instances.getJSONObject(i);
            String value = instance.getString(singleColumnName);
            if(singleColumnValueList.contains(value)){
                existJSONArray.add(instance);
            }
        }
    }

    private void distinguishByMultipleUniqueField(FlowContext flowContext){
        JSONArray existJSONArray = (JSONArray) flowContext.getData("existJSONArray");
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);
        JSONArray instances = (JSONArray) flowContext.checkData("instances");

        flowContext.executeFlowList(new GetUniqueFieldValueListFlow());
        List<String> uniqueFieldValueList = (List<String>) flowContext.getData("uniqueFieldValueList");
        if(uniqueFieldValueList.isEmpty()){
            return;
        }

        StringBuilder uniqueFieldNameValueBuilder = new StringBuilder();
        for(int i=0;i<instances.size();i++){
            JSONObject instance = instances.getJSONObject(i);

            uniqueFieldNameValueBuilder.setLength(0);
            for(String uniqueFieldName:manipulationOption.uniqueFieldNames){
                String uniqueFieldValue = instance.getString(uniqueFieldName);
                uniqueFieldNameValueBuilder.append(uniqueFieldValue+"|");
            }
            if(uniqueFieldValueList.contains(uniqueFieldNameValueBuilder.toString())){
                existJSONArray.add(instance);
            }
        }
    }

    private void setNotExistJSONObjectSet(FlowContext flowContext){
        JSONArray existJSONArray = (JSONArray) flowContext.getData("existJSONArray");
        JSONArray instances = (JSONArray) flowContext.checkData("instances");

        if(existJSONArray.isEmpty()){
            flowContext.putData("notExistJSONArray", instances);
            return;
        }

        JSONArray notExistJSONArray = new JSONArray();
        for(int i=0;i<instances.size();i++){
            JSONObject instance = instances.getJSONObject(i);
            if(!existJSONArray.contains(instance)){
                notExistJSONArray.add(instance);
            }
        }
        flowContext.putData("notExistJSONArray", notExistJSONArray);
    }

}
